<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>全球行动计算器v0.2测试版</title>
    <!-- 引入 echarts.js -->
    <script src="./echarts.min.js"></script>
</head>
<body>
    <!-- 为ECharts准备一个具备大小（宽高）的Dom -->
    <div class="main" style="width: 1500px;height:1500px;"></div>
    <div>分钟产量|初始资源|分|秒</div>
    <input type="text" id="perMinuteMoney" value=0 class="textClass"style="width: 40px;">
    <input type="text" id="money_future_max" value=0 class="textClass"style="width: 40px;">
    <input type="text" id="m" value=0 class="textClass"style="width: 15px;">
    <input type="text" id="s" value=0 class="textClass"style="width: 15px;">
    <button onclick="InitSource()">产生2分钟初始Money数据</button>
    <button onclick="AddSource()">增加2分钟的Money数据</button>
    <button onclick="start_calculate()">开始运行</button>
    <button onclick="end_calculate()">停止运行</button>
    <button onclick="change_perMoney_now()">校准"当前"每分钟获取资金数(根据"分钟产量"输入框)</button>
    <br/>
    <input type="text" id="set_money_now" value=0 class="textClass"style="width: 40px;">
    <button onclick="set_money_now()">校准"当前"钱数</button>
    <input type="text" id="use_money_now" value=0 class="textClass"style="width: 40px;">
    <button onclick="use_money_now()">"当前"花钱</button>
    <br/>
    <div>推演对局功能-控制按钮</div>
    <div>
        time_index:<input type="text" id="time_index" value=0 class="textClass"style="width: 40px;">
        pay:<input type="text" id="pay" value=0 class="textClass"style="width: 40px;">
        reason:<input type="text" id="reason" value="无" class="textClass"style="width: 80px;">
        <button onclick="use_money_UI()">use_money(time_index, pay, reason)函数</button>
        <br/>
        money_number:<input type="text" id="money_number" value=0 class="textClass"style="width: 40px;">
        <button onclick="set_money_UI()">set_money(time_index, money_number)函数</button>
        <br/>
        minuteMoney:<input type="text" id="minuteMoney" value=0 class="textClass"style="width: 40px;">
        <button onclick="change_perMoney_UI()">change_perMoney(time_index, minuteMoney)函数</button>
    </div>
    <br/>
    <div>导入导出图表数据</div>
    <div>
        [导入]total_data_json:<input type="text" id="total_data_json" class="textClass"style="width: 100px;height:50px">
        <button onclick="JSONToobj_UI()">JSONToobj(total_data_json)函数(导入图表数据)</button>
        <br/>
        [导出]total_data_json:<input type="text" id="total_data_json_out" class="textClass"style="width: 100px;height:50px">
        <button onclick="objToJSON_UI()">objToJSON()函数(导出图表数据)</button>
    </div>


    <br/>
    <div>标注线设置</div>
    <button onclick="change_money_label('BLUE_ALL')">(蓝军)显示全部建筑</button>
    <button onclick="change_money_label('BLUE_NO_DEF')">(蓝军)不包含防御塔</button>
    <button onclick="change_money_label('BLUE_NO_SHIP')">(蓝军)不包含船场</button>
    <button onclick="change_money_label('BLUE_NO_NOW_TIME')">(蓝军)不包含"当前时间"</button>
    

    <div>
        实时计算功能使用方法:
        <br/>
        STEP1:首先在第一个输入框内输入你的每分钟产量,当前资源数,点击"产生一组数据"
        <br/>
        STEP2:当你的游戏运行到 00:32秒(即本软件的"当前时间")时 点击本软件的"开始运行",这样游戏内时间就和本软件同步了
        <br/>
        STEP3:在"校准当前钱数"按钮前的方框内,输入你游戏内当前资金数,点击"校准当前钱数"按钮进行资金校准
        <br/>
        STEP4:如果你游戏内"补给中心"的数目发生改变,此时需要校准每分钟获取钱数
        此时应该在"分钟产量"输入框内输入你新的资源产量,然后点击"读入当前每分钟获取资金数"按钮
        <br/>
        STEP5:在图表内移动鼠标可以看见参考线,点击"标注线设置"下方的按钮可以切换标注线种类,点击"停止运行"后,可以拉动图表下方滑动条查看资金消耗走向
        <br/><br/><br/>
        作者:TXT85
        <br/>
        留言:目前是 v0.2 测试版本,本人技术渣,请轻喷 2020/8/17/3:26
    </div>
    <script type="text/javascript">
        label={
            "BLUE_ALL":[
                {yAxis: 300,label: {formatter: '300 电厂 工地 24s 机场 40s 船坞三级 72s 火箭塔 64s 鱼雷塔 56s'}},
                {yAxis: 400,label: {formatter: '400 资源 32s 空军三级 80s 指挥二级 48s'}},
                {yAxis: 100,label: {formatter: '100 兵营 一级16s 二级24s 三级32s '}},
                {yAxis: 180,label: {formatter: '180 车场一级 24s'}},
                {yAxis: 210,label: {formatter: '                                    210 车场二级 36s'}},
                {yAxis: 290,label: {formatter: '\n290 车场三级 48s'}},
                {yAxis: 200,label: {formatter: '200 特车一级 32s'}},
                {yAxis: 250,label: {formatter: '250 特车二级 48s 空军一级 48s'}},
                {yAxis: 320,label: {formatter: '320 特车三级 64s 空军二级 64s'}},
                {yAxis: 150,label: {formatter: '150 船坞一级 40s'}},
                {yAxis: 220,label: {formatter: '220 船坞二级 56s'}},
                {yAxis: 1000,label: {formatter: '1000 超武 80s'}},
                {yAxis: 140,label: {formatter: '\n140 碉堡 40s'}},
                {yAxis: 270,label: {formatter: '270 防空塔 48s'}},
                {yAxis: 800,label: {formatter: '800 指挥三级 64s'}},
                {yAxis: 1500,label: {formatter: '1500 指挥四级 80s'}},
                [{x:365, y:20},{x:365, y:1470,label: {formatter: '当前时间'}}]
            ],
            "BLUE_NO_DEF":[
                {yAxis: 300,label: {formatter: '300 电厂 工地 24s 机场 40s 船坞三级 72s'}},
                {yAxis: 400,label: {formatter: '400 资源 32s 空军三级 80s 指挥二级 48s'}},
                {yAxis: 100,label: {formatter: '100 兵营 一级16s 二级24s 三级32s '}},
                {yAxis: 180,label: {formatter: '180 车场一级 24s'}},
                {yAxis: 210,label: {formatter: '                                    210 车场二级 36s'}},
                {yAxis: 290,label: {formatter: '\n290 车场三级 48s'}},
                {yAxis: 200,label: {formatter: '200 特车一级 32s'}},
                {yAxis: 250,label: {formatter: '250 特车二级 48s 空军一级 48s'}},
                {yAxis: 320,label: {formatter: '320 特车三级 64s 空军二级 64s'}},
                {yAxis: 150,label: {formatter: '150 船坞一级 40s'}},
                {yAxis: 220,label: {formatter: '220 船坞二级 56s'}},
                {yAxis: 800,label: {formatter: '800 指挥三级 64s'}},
                {yAxis: 1500,label: {formatter: '1500 指挥四级 80s'}},
                [{x:365, y:20},{x:365, y:1470,label: {formatter: '当前时间'}}]
            ],
            "BLUE_NO_SHIP":[
                {yAxis: 300,label: {formatter: '300 电厂 工地 24s 机场 40s'}},
                {yAxis: 400,label: {formatter: '400 资源 32s 空军三级 80s 指挥二级 48s'}},
                {yAxis: 100,label: {formatter: '100 兵营 一级16s 二级24s 三级32s '}},
                {yAxis: 180,label: {formatter: '180 车场一级 24s'}},
                {yAxis: 210,label: {formatter: '                                    210 车场二级 36s'}},
                {yAxis: 290,label: {formatter: '\n290 车场三级 48s'}},
                {yAxis: 200,label: {formatter: '200 特车一级 32s'}},
                {yAxis: 250,label: {formatter: '250 特车二级 48s 空军一级 48s'}},
                {yAxis: 320,label: {formatter: '320 特车三级 64s 空军二级 64s'}},
                {yAxis: 800,label: {formatter: '800 指挥三级 64s'}},
                {yAxis: 1500,label: {formatter: '1500 指挥四级 80s'}},
                [{x:365, y:20},{x:365, y:1470,label: {formatter: '当前时间'}}]
            ],
            "BLUE_NO_NOW_TIME":[
                {yAxis: 300,label: {formatter: '300 电厂 工地 24s 机场 40s 船坞三级 72s'}},
                {yAxis: 400,label: {formatter: '400 资源 32s 空军三级 80s 指挥二级 48s'}},
                {yAxis: 100,label: {formatter: '100 兵营 一级16s 二级24s 三级32s '}},
                {yAxis: 180,label: {formatter: '180 车场一级 24s'}},
                {yAxis: 210,label: {formatter: '                                    210 车场二级 36s'}},
                {yAxis: 290,label: {formatter: '\n290 车场三级 48s'}},
                {yAxis: 200,label: {formatter: '200 特车一级 32s'}},
                {yAxis: 250,label: {formatter: '250 特车二级 48s 空军一级 48s'}},
                {yAxis: 320,label: {formatter: '320 特车三级 64s 空军二级 64s'}},
                {yAxis: 150,label: {formatter: '150 船坞一级 40s'}},
                {yAxis: 220,label: {formatter: '220 船坞二级 56s'}},
                {yAxis: 800,label: {formatter: '800 指挥三级 64s'}},
                {yAxis: 1500,label: {formatter: '1500 指挥四级 80s'}}
            ],
        }
            

        var myChart = echarts.init(document.getElementsByClassName('main')[0]);

        //两个 yAxis，共享了一个 xAxis。
        //两个 series，也共享了这个 xAxis，但是分别使用不同的 yAxis，
        //使用 yAxisIndex 来指定它自己使用的是哪个 yAxis：
        var option2 = {
            dataset: {
                source: [["chart"],["money"]]
            },
            dataZoom:[
                {
                    type: 'slider',
                    rangeMode: ['value', 'value'],
                    startValue:0,
                    endValue:59
                }
            ],
            legend: {},
            tooltip: {
                trigger: 'axis',
                axisPointer:{
                    type: 'cross'
                },
                formatter: function (obj) {
                    if(obj[1]){
                        let money_val = obj[0].value;
                        let action_val = obj[1].value;
                        return '当前数据<br/>'
                        +'时间: '+money_val[0].split("\n")[0]+'<br/>'
                        +'资金: '+money_val[1]+'<br/>'
                        +'扣除资金: '+action_val[2]+'<br/>'
                        +'行为: '+action_val[3]+'<br/>'
                    }
                    let money_val = obj[0].value;
                    return '当前数据<br/>'
                    +'时间:'+money_val[0].split("\n")[0]+'<br/>'
                    +'资金:'+money_val[1]+'<br/>'
                    ;
                }
            },
            xAxis: [
                {
                    type: 'category'
                },
            ],
            /*yAxis: [
                {
                    min:0,
                    max:2000,
                    gridIndex: 0,
                    interval: 50
                },
                {
                    alignWithLabel:true,
                    type: 'category',
                    data:["电厂","车场"],
                    boundaryGap: ['20%', '20%']
                },
            ],*/
            yAxis: {
                    min:0,
                    max:1600,
                    gridIndex: 0,
                    interval: 50
                },
            grid: {
                    top:'1%',
                    bottom: '5%',
                    right:'20%',
                    left:'5%'
                },
            series: [
                // 这几个系列会在第一个直角坐标系中，每个系列对应到 dataset 的每一行。
                {
                    showSymbol: false,
                    hoverAnimation: false,
                    type: 'line', 
                    seriesLayoutBy: 'row',
                    markLine: {
                        data: label["NO_DEF"]
                    },
                    dimensions:['money']
                },
                {
                    showSymbol: false,
                    hoverAnimation: false,
                    type: 'scatter',
                    seriesLayoutBy: 'row',
                    //dimensions:['money']
                    data: []
                }
            ]
        }
        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option2);

        //一些全局变量
        //思路:整个图表实际上着重更新的是"图表最右侧数据",也就是所谓的"最最未来"的数据
        //之所以不把"现在"直接放在图表最右侧,是因为我需要"预测"资金增长过程

        let perMoney=0;//每"time_interval"秒增加的钱数(当前time_interval取2)
        let money_future_max=0;//图表中最最未来的[钱数],即图表最右侧边缘的值[钱数]
        let time_future_max={m:0,s:0};//图表中最最未来的[时间],即图表最右侧边缘的值[时间]
        let time_now=0;//当前时间<此值并不是实时最新!!每次使用请手动计算>,实际上是x轴时间数据的index值,默认是[最未来时间] - 45格,由[最未来时间]计算得到
        let time_interval=2;//计算的时间最小间隔
        let data=[["chart"],["money"]];
        let timer=null;//计时器(js的setInterval计时器对象)

        //初始化第一组数据的函数
        function InitSource(){
            //option2.series[1].data=[['0:32\n16', 120, 200,"突击兵*5"]];
            option2.series[1].data=[];//把action数据归零
            data=[["chart"],["money"]];//把Money数据归零
            perMoney = parseInt(document.getElementById("perMinuteMoney").value,10) / (60/time_interval);
            money_future_max = parseInt(document.getElementById("money_future_max").value,10);
            time_future_max.m=parseInt(document.getElementById("m").value,10);
            time_future_max.s=parseInt(document.getElementById("s").value,10);
            while((time_future_max.s%10)!=0){
                time_future_max.s-=1;
            }

            for(let i=0;i<120/time_interval;i++){
                money_future_max+=perMoney;
                if((time_future_max.s+time_interval)>=60){
                    time_future_max.m+=1;
                    time_future_max.s=0;
                }else{
                    time_future_max.s+=time_interval;
                }
                data[0].push(time_future_max.m.toString()+";"+time_future_max.s.toString() + "\n" +(data[0].length).toString());
                data[1].push(money_future_max);
            }
            option2.dataset.source=data;
            myChart.setOption(option2);
        }
        //额外增加两分钟的Money数据的函数
        function AddSource(){
            for(let i=0;i<120/time_interval;i++){
                money_future_max+=perMoney;
                if((time_future_max.s+time_interval)>=60){
                    time_future_max.m+=1;
                    time_future_max.s=0;
                }else{
                    time_future_max.s+=time_interval;
                }
                data[0].push(time_future_max.m.toString()+";"+time_future_max.s.toString() + "\n" +(data[0].length).toString());
                data[1].push(money_future_max);
            }
            option2.dataset.source=data;
            myChart.setOption(option2);
        }

        //切换标注线
        function change_money_label(type){
            option2.series[0].markLine.data=label[type]
            myChart.setOption(option2);
        }

        //此函数每帧调用
        function makesource_time(){
            time_interval=2;
            money_future_max+=perMoney;
            if((time_future_max.s+time_interval)>=60){
                time_future_max.m+=1;
                time_future_max.s=0;
            }else{
                time_future_max.s+=time_interval;
            }
            //data[0]是x轴(type为类目轴)的数据,是"时间",加上"\n"换行是为了表示"这是第几组 时间-资金 数据(数据组数以0开始)"
            data[0].push(time_future_max.m.toString()+";"+time_future_max.s.toString() + "\n" +(data[0].length).toString());
            data[1].push(money_future_max);

            option2.dataset.source=data;
            option2.dataZoom[0].startValue=data[1].length - 60;
            option2.dataZoom[0].endValue=data[1].length - 1;
            myChart.setOption(option2);
        }
        //***!!!关键函数!!!***
        //直接设置某一时刻"time_index"的[资金数] 的函数,即让time_index后方所有数据的钱数减去"pay"的大小
        function set_money(time_index, money_number){
            data[1][time_index]=money_number;
            for(let i=(time_index + 1);i<data[1].length;i++){
                data[1][i]=data[1][i-1] + perMoney;
            }
            //记得修改"最未来的钱数",否则接下来的"计算"会出bug
            money_future_max=data[1][data[1].length-1];
            //更新图表option
            option2.dataset.source=data;
            myChart.setOption(option2);
        }
        function set_money_UI(){
            let time_index = parseInt(document.getElementById("time_index").value,10);
            let money_number = parseInt(document.getElementById("money_number").value,10);
            set_money(time_index, money_number);
        }
        //
        function set_money_now(){
            let money_temp = parseInt(document.getElementById("set_money_now").value,10);
            time_now=data[0].length - 45;//当前时间,实际上是x轴时间数据的index值,默认是[最未来时间] - 45格,由[最未来时间]计算得到
            set_money(time_now, money_temp);
        }

        //在某一时刻"time_index"花掉 "pay"元 的函数,即让time_index后方所有数据的钱数减去"pay"的大小
        //参数表:
        //time_index:整数 data[0][time_index],即时间轴数据的数组下标,因为时间轴是"类目轴",所以只能用数组下标
        //pay:整数 花费的钱数
        //reason:字符串 花钱的理由
        function use_money(time_index, pay, reason){
            //对money的数据进行修改
            if(data[1][time_index]<pay){
                console.log("资金不足");
                return;
            }
            //for循环修改"花钱"时间之后的所有money数据
            for(let i=time_index;i<data[1].length;i++){
                data[1][i]-=pay;
            }
            //更新"最未来的钱数"
            money_future_max=data[1][data[1].length-1];
            //在当前时间添加action数据,即这笔钱花来干嘛了
            //[data[0][time_index] (这个是类目轴的完全名字) , data[1][time_index] (这个填写当前钱数,为了和资金曲线重合上) , pay(这个时间花掉的钱数), reason(花钱的理由)]
            option2.series[1].data.push([data[0][time_index], data[1][time_index], pay, reason]);
            //option2.series[1].data=[['0:32\n15', 120, 200,"突击兵*5"]];
            
            //更新图表option
            option2.dataset.source=data;
            myChart.setOption(option2);
        }
        //使用浏览器UI的use_money_UI函数
        function use_money_UI(){
            let time_index = parseInt(document.getElementById("time_index").value,10);
            let pay = parseInt(document.getElementById("pay").value,10);
            let reason = document.getElementById("pay").value;
            use_money(time_index, pay, reason);
        }
        //在[当前时刻]time_now花钱的函数
        function use_money_now(){
            let pay = parseInt(document.getElementById("use_money_now").value,10);
            time_now=data[0].length - 45;//当前时间,实际上是x轴时间数据的index值,默认是[最未来时间] - 45格,由[最未来时间]计算得到
            use_money(time_now,pay," ");
        }
        //停止运行
        function end_calculate(){
            if ( timer ){
                clearInterval(timer);
            }
        }
        //开始运行
        function start_calculate(){
            end_calculate();
            timer = setInterval("makesource_time()",1000*time_interval);
        }
        //修改time_index的每分钟获取资金数(实际上就是更新perMoney,然后调用set_money)
        function change_perMoney(time_index, minuteMoney){
            //从"分钟产量"输入框获取"当前分钟产量"
            perMoney = parseInt(minuteMoney) / (60/time_interval);
            set_money(time_index, data[1][time_index]);
        }
        function change_perMoney_UI(){
            let time_index = parseInt(document.getElementById("time_index").value,10);
            let minuteMoney = parseInt(document.getElementById("minuteMoney").value,10);
            change_perMoney(time_index, minuteMoney);
        }
        //在运行中,修改当前每分钟获取资金数
        function change_perMoney_now(){
            //从"分钟产量"输入框获取"当前分钟产量"
            perMoney = parseInt(document.getElementById("perMinuteMoney").value,10) / (60/time_interval);
            time_now=data[1].length - 45;
            set_money(time_now, data[1][time_now]);
        }

        //{输出图标数据} 把当前图表所需全部数据放进json中,并在控制台显示
        function objToJSON(){
            let total_data = {"money_data":data,"action_data":option2.series[1].data};
            let total_data_json = JSON.stringify(total_data);
            //JSON.parse(total_data_json);
            console.log(escape(total_data_json));
            return escape(total_data_json);
        }
        function objToJSON_UI(){
            document.getElementById("total_data_json_out").value=objToJSON();

        }
        //{读入图标数据} 把JSON解析为当前图表所需数据,并且更新图标为这组数据
        //关于JSON.parse无法解析"\n"等转义字符的问题
        //JSON.parse直接读入包含"\n"的外部字符串会报错
        //既然JSON.parse不能解析转义字符,那么我在生成数据的时候,就对total_data_json使用escape()进行编码,然后再unescape()解码成为js内部的[字符串对象]后,再使用JSON.parse
        function JSONToobj(total_data_json){
            total_data = JSON.parse(unescape(total_data_json));
            data=total_data["money_data"];
            option2.series[1].data=total_data["action_data"];
            option2.dataset.source=data;
            myChart.setOption(option2);
        }
        function JSONToobj_UI(){
            let total_data_json = document.getElementById("total_data_json").value;
            if(total_data_json==undefined||total_data_json==null||total_data_json==""){
                return;
            }
            JSONToobj(total_data_json);
        }

    </script>
</body>
</html>

<!--范例数据:option2.series[1].data=[['0:32\n16', 120, 200,"突击兵*5"]];-->